﻿Imports System.Runtime.InteropServices

Namespace OpenCL
    Public Class CommandQueue
        Public Property InternalPointer() As IntPtr
            Get
                Return m_InternalPointer
            End Get
            Private Set(ByVal value As IntPtr)
                m_InternalPointer = value
            End Set
        End Property
        Private m_InternalPointer As IntPtr
        Public Sub New(ByVal context As Context, ByVal device As IntPtr)
            Dim [error] As Integer
            InternalPointer = OpenCLAPI.clCreateCommandQueue(context.InternalPointer, device, 0, [error])
        End Sub
        Protected Overrides Sub Finalize()
            Try
                OpenCLAPI.clReleaseCommandQueue(InternalPointer)
            Finally
                MyBase.Finalize()
            End Try
        End Sub

        Public Sub ReadBuffer(Of T As Structure)(ByVal buffer As Buffer, ByVal systemBuffer As T())
            Dim handle As GCHandle = GCHandle.Alloc(systemBuffer, GCHandleType.Pinned)

            OpenCLAPI.clEnqueueReadBuffer(InternalPointer, buffer.InternalPointer, True, 0, Math.Min(buffer.SizeInBytes, Marshal.SizeOf(GetType(T)) * systemBuffer.Length), handle.AddrOfPinnedObject(), _
             0, IntPtr.Zero, IntPtr.Zero)

            handle.Free()
        End Sub

        Public Sub EnqueueTask(ByVal kernel As Kernel)
            OpenCLAPI.clEnqueueTask(InternalPointer, kernel.InternalPointer, 0, Nothing, IntPtr.Zero)
        End Sub

        Public Sub EnqueueRange(ByVal kernel As Kernel, ByVal globalWorkSize As MultiDimension, ByVal localWorkSize As MultiDimension)
            Dim offset As New MultiDimension()
            OpenCLAPI.clEnqueueNDRangeKernel(InternalPointer, kernel.InternalPointer, globalWorkSize.Dimension, offset, globalWorkSize, localWorkSize, _
             0, Nothing, IntPtr.Zero)
        End Sub

    End Class

    Public Class CommandQueueCollection
        Inherits System.Collections.Generic.List(Of CommandQueue)

        Public Sub Load(ByVal contxt As Context, ByVal deviceID As IntPtr)
            Me.Add(New CommandQueue(contxt, deviceID))
        End Sub

    End Class
End Namespace